﻿using System;
using System.Collections.Generic;
using Microsoft.Practices.SLUnity;
using System.Windows.Media;
using Microsoft.Practices.ObjectBuilder2;
using Stoplight.Enums;
using Stoplight.Events;
using Stoplight.Base;
using System.Windows.Controls;
using Stoplight.Views.StatusBar;
using Stoplight.Constants;
using Stoplight.Interfaces;

namespace StopLight {
    public class StoplightPresenter : PresenterBase<IStoplightView>
    {
        [Dependency]
        public IStoplightService Stoplight {get; set; }

        [Dependency]
        public IStoplightScheduleService Schedule { get; set; }

        private Brush CurrentColor 
        {
            get { return FindName<StackPanel>("splLightPanel").Background; }
            set { FindName<StackPanel>("splLightPanel").Background = value; }
        }
        private string GreenDuration
        {
            get { return FindName<TextBox>("txtGreenDuration").Text; }
            set { FindName<TextBox>("txtGreenDuration").Text = value; }
        }
        private string YellowDuration
        {
            get { return FindName<TextBox>("txtYellowDuration").Text; }
            set { FindName<TextBox>("txtYellowDuration").Text = value; }
        }
        private string RedDuration
        {
            get { return FindName<TextBox>("txtRedDuration").Text; }
            set { FindName<TextBox>("txtRedDuration").Text = value; }
        }


        protected override void OnViewSet()
        {
            // Set status bar
            FindName<ItemsControl>("stsViewStatusBar").Items.Add(
                UnityContainer.Resolve<IStatusBarView>());

            // Subscribe to light changed event
            EventAggregator.GetEvent<LightChangedEvent>().Subscribe(OnLightChanged);

            GreenDuration = "3000";
            YellowDuration = "500";
            RedDuration = "5000";

            CurrentColor = new SolidColorBrush(Colors.Green);

            Schedule.Update(TimeSpan.FromMilliseconds(3000),
                            TimeSpan.FromMilliseconds(500),
                            TimeSpan.FromMilliseconds(5000));

            Schedule.Start();
        }

        public void OnLightChanged(LightChangedEvent e)
        {
            switch (e.CurrentColor)
            {
                case StoplightColors.Green:
                    CurrentColor = new SolidColorBrush(Colors.Green);
                    break;

                case StoplightColors.Yellow:
                    CurrentColor = new SolidColorBrush(Colors.Yellow);
                    break;

                case StoplightColors.Red:
                    CurrentColor = new SolidColorBrush(Colors.Red);
                    break;
            }
        }

        protected override void OnButtonClick(Button button, ButtonEventArgs e)
        {
            switch (e.TagString)
            {
                case "UPDATE":
                    OnViewUpdateClicked(button, e);
                    break;

                case "CHANGE":
                    Schedule.ForceChange();
                    break;
            }
        }


        private void OnViewUpdateClicked(object sender, EventArgs e) {
            string[] durationsAsString = new string[3];
            List<string> propNames = new List<string>(new string[]
			{
				StoplightConstants.GreenDuration,
				StoplightConstants.YellowDuration,
				StoplightConstants.RedDuration
			});

            foreach (string propName in propNames) {
                ActOnProperty(propName,
                delegate { durationsAsString[0] = GreenDuration; },
                delegate { durationsAsString[1] = YellowDuration; },
                delegate { durationsAsString[2] = RedDuration; }
                );
            }

            TimeSpan[] timeSpans = ArrayHelper.ConvertAll<string, TimeSpan>(durationsAsString,
            delegate(string s) {
                return TimeSpan.FromMilliseconds(int.Parse(s));
            });

            Schedule.Update(timeSpans[0], timeSpans[1], timeSpans[2]);
        }

        private delegate void Action();
        private void ActOnProperty(
            string propertyName, Action greenAction, Action yellowAction, Action redAction)
        {
            switch (propertyName)
            {
                case StoplightConstants.GreenDuration:
                    greenAction();
                    break;

                case StoplightConstants.YellowDuration:
                    yellowAction();
                    break;

                case StoplightConstants.RedDuration:
                    redAction();
                    break;

                case StoplightConstants.CurrentColor:
                    return;
            }
        }

    }
}
